// middleware/log_middleware.go
// =============================================================================
// | 包: middleware                                                           |
// | 功能: 提供HTTP请求日志记录中间件                                          |
// | 版本: 1.0.0                                                              |
// =============================================================================
package middleware

import (
	"blog_server/service/log_service" // 日志服务包 - 提供日志记录功能
	"fmt"                             // 格式化包 - 用于字符串格式化和输出
	"net/http"

	"github.com/gin-gonic/gin" // Web框架 - 提供HTTP路由和处理功能
)

// =============================================================================
// | 结构体: ResponseWriter                                                   |
// | 功能: 包装Gin响应写入器，用于捕获HTTP响应体                               |
// | 字段: ResponseWriter - gin.ResponseWriter - 原始响应写入器                |
// | 字段: Body - []byte - 存储捕获的响应体内容                                 |
// | 字段: Head - http.Header - 存储捕获的响应头信息                            |
// =============================================================================
type ResponseWriter struct {
	gin.ResponseWriter
	Body []byte       // 存储捕获的响应体内容
	Head http.Header  // 存储捕获的响应头信息
}

// =============================================================================
// | 函数: Write                                                              |
// | 参数: @data - []byte - 要写入的响应数据                                   |
// | 返回: @int - 写入的字节数                                                |
// | 返回: @error - 写入过程中可能发生的错误                                   |
// | 功能: 重写ResponseWriter的Write方法，捕获响应体内容                        |
// | 说明: 在写入响应的同时，保存响应数据到Body字段                            |
// |----------------------------------------------------------------------------|
// | 流程:                                                                     |
// | 1. 将响应数据添加到Body字段中                                             |
// | 2. 打印响应数据到控制台                                                   |
// | 3. 调用原始响应写入器的Write方法完成实际写入                              |
// =============================================================================
func (w *ResponseWriter) Write(data []byte) (int, error) {
	w.Body = append(w.Body, data...)         // 将响应数据添加到Body字段中
	fmt.Printf("response: %s", string(data)) // 打印响应数据到控制台
	return w.ResponseWriter.Write(data)      // 调用原始响应写入器的Write方法完成实际写入
}

// =============================================================================
// | 函数: Header                                                             |
// | 参数: 无                                                                 |
// | 返回: @http.Header - HTTP响应头信息                                       |
// | 功能: 获取响应写入器的HTTP响应头信息                                      |
// | 说明: 重写ResponseWriter的Header方法，返回自定义的Head字段                |
// =============================================================================
func (w *ResponseWriter) Header() http.Header {
	return w.Head
}

// =============================================================================
// | 函数: LogMiddleware                                                      |
// | 参数: @c - *gin.Context - Gin上下文对象，包含请求和响应信息               |
// | 返回: 无                                                                  |
// | 功能: HTTP请求日志记录中间件                                              |
// | 说明: 捕获并记录HTTP请求和响应信息，存储到日志系统                        |
// |----------------------------------------------------------------------------|
// | 流程:                                                                     |
// | 1. 根据Gin上下文创建新的日志记录对象                                      |
// | 2. 设置请求信息到日志对象中                                               |
// | 3. 将日志对象存储在上下文对象中，供后续处理使用                            |
// | 4. 创建ResponseWriter实例，用于捕获响应体                                 |
// | 5. 替换上下文的Writer，使其使用我们的ResponseWriter                       |
// | 6. 调用Next()方法，执行后续处理函数                                       |
// | 7. 处理完成后，打印响应头信息                                             |
// | 8. 设置响应体信息到日志对象                                               |
// | 9. 设置响应头信息到日志对象                                               |
// | 10. 保存日志记录到存储系统                                                |
// =============================================================================
func LogMiddleware(c *gin.Context) {
	log := log_service.NewActionLogByGin(c) // 根据Gin上下文创建新的日志记录对象

	// 请求中间件 - 记录请求开始时间
	// start := time.Now()

	log.SetRequest(c) // 设置请求信息到日志对象中
	c.Set("log", log) // 将日志对象存储在上下文对象中，供后续处理使用

	res := &ResponseWriter{ // 创建ResponseWriter实例，用于捕获响应体
		ResponseWriter: c.Writer,
		Head:           make(http.Header),
	}
	c.Writer = res // 替换上下文的Writer，使其使用我们的ResponseWriter

	c.Next() // 调用Next()方法，执行后续处理函数

	// 响应中间件 - 记录处理耗时和状态
	fmt.Println(res.Head) // 打印响应头信息

	log.SetResponse(res.Body)       // 处理完成后，设置响应信息到日志对象
	log.SetResponseHeader(res.Head) // 设置响应头信息到日志
	log.MiddlewareSave()            // 保存日志记录到存储系统

	// duration := time.Since(start)
	// logrus.Infof("请求处理完成，耗时: %v", duration)
}
